import socket 
import select
from datetime import datetime
import cv2
import numpy as np
import time
import os

# 配置
SERVER_IP = "127.0.0.1"
SERVER_PORT = 8004
HEARTBEAT_MSG = b'HEARTBEAT'
MSG_LENGTH = 100000

# 视频录制相关变量
video_writer = None
video_start_time = None
video_duration = 10 * 60  # 10分钟，单位秒
frame_size = (640, 480)  # 需要根据实际图像尺寸调整

# 视频存储配置
VIDEO_DIR = "videos"  # 视频存储目录
MAX_VIDEO_FILES = 24   # 最大视频文件数量（24个文件 = 4小时）

# 初始化
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client_socket.setblocking(False)
server_address = (SERVER_IP, SERVER_PORT)

# 创建视频目录
if not os.path.exists(VIDEO_DIR):
    os.makedirs(VIDEO_DIR)
    print(f"创建视频目录: {VIDEO_DIR}")

print(f"客户端启动，连接 {SERVER_IP}:{SERVER_PORT}...")

def init_video_writer():
    """初始化视频写入器"""
    global video_writer, video_start_time
    
    # 获取当前日期和时间作为文件名
    timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
    filename = os.path.join(VIDEO_DIR, f"{timestamp}.mp4")
    
    # 创建视频写入器
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    video_writer = cv2.VideoWriter(filename, fourcc, 30.0, frame_size)
    video_start_time = time.time()
    
    print(f"开始录制视频: {filename}")

def cleanup_old_videos():
    """清理旧的视频文件，保持文件数量不超过限制"""
    try:
        # 获取目录中所有的.mp4文件
        video_files = [f for f in os.listdir(VIDEO_DIR) if f.endswith('.mp4')]
        
        if len(video_files) > MAX_VIDEO_FILES:
            # 按文件名排序（因为文件名包含时间戳，所以按字母排序就是按时间排序）
            video_files.sort()
            
            # 计算需要删除的文件数量
            files_to_delete = len(video_files) - MAX_VIDEO_FILES
            
            # 删除最早的文件
            for i in range(files_to_delete):
                file_to_delete = os.path.join(VIDEO_DIR, video_files[i])
                os.remove(file_to_delete)
                print(f"删除旧视频文件: {video_files[i]}")
                
    except Exception as e:
        print(f"清理旧视频文件时出错: {e}")

def check_and_rotate_video():
    """检查是否需要创建新的视频文件（每10分钟）"""
    global video_writer, video_start_time
    
    if video_writer is None:
        init_video_writer()
    elif time.time() - video_start_time >= video_duration:
        # 关闭当前视频文件
        video_writer.release()
        video_writer = None
        print(f"视频已保存，时长: {video_duration}秒")
        
        # 清理旧视频文件
        cleanup_old_videos()
        
        # 立即开始新的视频录制
        init_video_writer()

try:
    while True:
        # 使用select监听套接字
        readable, _, _ = select.select([client_socket], [], [], 1)
        
        for sock in readable:
            if sock == client_socket:
                # 接收服务端消息
                data, server_data = client_socket.recvfrom(MSG_LENGTH)
                nparr = np.frombuffer(data, np.uint8)
                decoded_frame = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
                
                if decoded_frame is not None:
                    # 检查是否需要创建新的视频文件
                    check_and_rotate_video()
                    
                    # 写入当前帧到视频
                    if video_writer is not None:
                        video_writer.write(decoded_frame)
                    
                    # 显示图像
                    cv2.imshow('imgs', decoded_frame)

                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break

        # 发送心跳
        client_socket.sendto(HEARTBEAT_MSG, server_address)

except KeyboardInterrupt:
    print("程序被用户中断")
finally:
    # 清理资源
    if video_writer is not None:
        video_writer.release()
        print("最后一个视频已保存")
    client_socket.close()
    cv2.destroyAllWindows()
    print("客户端已关闭")